package org.stream.answerduel.vo;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.paho.client.mqttv3.MqttException;
import org.stream.answerduel.service.*;
import org.stream.answerduel.util.SnowflakeIdWorker;
import org.stream.answerduel.vo.Message.JoinRoomMessage;
import org.stream.answerduel.vo.Message.PvpMessage;
import org.stream.answerduel.vo.Message.QuitRoomMessage;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Data
@Slf4j
public class WaitingRoom
{
    private List<WaitingUser> waitingUsers = new ArrayList<WaitingUser>(2);
    private String roomID;
    private MQService mqService;
    private UserService userService;
    private SubjectService subjectService;
    private Timer destroyTimer = new Timer();
    private Timer autoPrepareTimer = new Timer();

    /**
     * 功能描述：创建一个好友对战的房间，房间将在10分钟后自动销毁
     * @param roomID 房间ID
     * @param user 创建房间的用户
     */
    public void create(String roomID, UserVo user, MQService mqService, UserService userService, SubjectService subjectService) {
        this.roomID = roomID;
        this.waitingUsers.add(new WaitingUser(user));
        this.waitingUsers.add(null);
        this.mqService = mqService;
        this.userService = userService;
        this.subjectService = subjectService;
        destroyAfterTime(roomID, 6000000);
    }

    public void destroyAfterTime(String roomID, long delay){
        destroyTimer.schedule(new TimerTask() 
        {
            public void run() {
                if(MatchThread.roomList.containsKey(roomID))
                    MatchThread.roomList.remove(roomID);
                
            }
        }, delay);
    }

    public void autoPrepareAfterTime(long delay){
        autoPrepareTimer.schedule(new TimerTask()
        {
            public void run() {
                try {
                    if (waitingUsers.get(0) != null)
                        setPrepare(0);
                    if (waitingUsers.get(1) != null)
                        setPrepare(1);
                }catch (MqttException e){
                    e.printStackTrace();
                }
            }
        }, delay);
    }

    /**
     * 功能描述：用户加入好友房间
     * @param user 需要加入的用户
     * @return 加入后的对手的对象，如果房间已满则返回null
     */
    public synchronized WaitingUser join(UserVo user)
    {
        if(this.isFull())
            return null;

        if(this.waitingUsers.get(0) == null)
        {
            this.waitingUsers.set(0,new WaitingUser(user));
            if(this.waitingUsers.get(1) != null) {
                JoinRoomMessage joinRoomMessage = new JoinRoomMessage();
                joinRoomMessage.setWaitingUser(waitingUsers.get(0));
                joinRoomMessage.setRoomId(roomID);
                try {
                    mqService.publish(joinRoomMessage.toString(), "/public/TEST/" + waitingUsers.get(1).getWechatID());
                    log.info(joinRoomMessage.toString());
                }catch (MqttException e){
                    e.printStackTrace();
                }
            }
            //autoPrepareAfterTime(10000);
            return waitingUsers.get(1);
        }
        if(this.waitingUsers.get(1) == null)
        {
            this.waitingUsers.set(1,new WaitingUser(user));
            if(waitingUsers.get(0) != null) {
                JoinRoomMessage joinRoomMessage = new JoinRoomMessage();
                joinRoomMessage.setWaitingUser(waitingUsers.get(1));
                joinRoomMessage.setRoomId(roomID);
                try {
                    mqService.publish(joinRoomMessage.toString(), "/public/TEST/" + waitingUsers.get(0).getWechatID());
                    log.info(joinRoomMessage.toString());
                }catch (MqttException e){
                    e.printStackTrace();
                }
            }
            //autoPrepareAfterTime(10000);
            return waitingUsers.get(0);
        }
        return null;
    }

    public synchronized void exit(long userID)
    {
        if(this.isEmpty())
            return;
        if(waitingUsers.get(0) != null && waitingUsers.get(0).getId().equals(userID))
        {
            waitingUsers.set(0, null);
            QuitRoomMessage quitRoomMessage = new QuitRoomMessage(userID);
            try {
                if(waitingUsers.get(1) != null) {
                    mqService.publish(quitRoomMessage.toString(), "/public/TEST/" + waitingUsers.get(1).getWechatID());
                    log.info(quitRoomMessage.toString());
                }
            }catch (MqttException e){
                e.printStackTrace();
            }
            return;
        }

        if(waitingUsers.get(1) != null && waitingUsers.get(1).getId().equals(userID))
        {
            waitingUsers.set(1, null);
            QuitRoomMessage quitRoomMessage = new QuitRoomMessage(userID);
            try {
                if(waitingUsers.get(0) != null) {
                    mqService.publish(quitRoomMessage.toString(), "/public/TEST/" + waitingUsers.get(0).getWechatID());
                    log.info(quitRoomMessage.toString());
                }
            }catch (MqttException e){
                e.printStackTrace();
            }
            return;
        }
    }

    public boolean isEmpty(){
        if(waitingUsers.get(0) == null && waitingUsers.get(1) == null)
            return true;
        else
            return false;
    }

    public boolean isFull(){
        if(waitingUsers.get(0) != null && waitingUsers.get(1) != null)
            return true;
        else
            return false;
    }

    public boolean hasUser(long userID){
        boolean has = false;
        for(int i=0;i<waitingUsers.size();i++){
            WaitingUser waitingUser = waitingUsers.get(i);
            if(waitingUser != null && waitingUser.getId().equals(userID))
            {
                has = true;
                break;
            }
        }
        return has;
    }

    public void setPrepare(int i) throws MqttException
    {
        WaitingUser me = waitingUsers.get(i);
        WaitingUser rival = waitingUsers.get((i+1)%2);

        if(me.isPrepare()){
            log.info("用户ID:"+me.getId()+"已经在好友房间准备过了");
            return;
        }

        log.info("用户ID:"+me.getId()+"好友房间准备完毕");
        me.setPrepare(true);
        if(rival != null && rival.isPrepare())//如果对手也准备好了，就放入对战房间
        {
            Room room = new Room();
            SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker();
            Long duelRoomID = snowflakeIdWorker.nextId();
            room.init(duelRoomID,waitingUsers.get(0),waitingUsers.get(1),mqService,userService,subjectService);
            MatchThread.roomList.put(duelRoomID, room);
            MatchThread.waitingRoomList.remove(this.roomID);

            log.info("好友对战开始，房间ID："+duelRoomID);

            try {
                PvpMessage pvpMessage = new PvpMessage(rival, duelRoomID);
                mqService.publish(pvpMessage.toString(), "/public/TEST/"+me.getWechatID());
                log.info(pvpMessage.toString()+me.getWechatID());

                pvpMessage = new PvpMessage(me, duelRoomID);
                mqService.publish(pvpMessage.toString(), "/public/TEST/"+rival.getWechatID());
                log.info(pvpMessage.toString()+rival.getWechatID());
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }

    public void cancelPrepare(int i){
        WaitingUser me = waitingUsers.get(i);
        me.setPrepare(false);
        log.info("用户ID:"+me.getId()+"好友房间取消准备");
    }
}